package com.bootlever.framework.webservice.configuration;

import com.alibaba.fastjson.JSON;
import com.bootlever.framework.common.utils.ResourceUtils;
import com.bootlever.framework.common.utils.StringUtils;
import com.bootlever.framework.webservice.bean.Server;
import com.bootlever.framework.webservice.constant.WebServiceConstant;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import javax.xml.ws.Endpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class BootleverBeanFactoryAware implements BeanFactoryAware,ApplicationContextAware,
        ApplicationListener<ContextRefreshedEvent>, WebServiceConstant {

    private static final Logger logger = LoggerFactory.getLogger(BootleverBeanFactoryAware.class);
    private DefaultListableBeanFactory beanFactory;
    private ApplicationContext applicationContext;

    @Autowired
    private SpringBus springBus;

    //实现BeanFactoryAware为了拿到beanFactory
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (DefaultListableBeanFactory) beanFactory;
    }

    public void onApplicationEvent(ContextRefreshedEvent event) {
        logger.info("开始初始化webService");
        try {
            Map<String,Object> map = ResourceUtils.scanResource(SERVER_CONFIG_LOCATION, Server.class);
            BeanDefinitionBuilder serverDefinitionBuilder = null;
            if (logger.isInfoEnabled()){
                logger.info("服务端：{}", JSON.toJSON(map));
            }
            for (Object object : map.values()) {
                List<Object> list = (List<Object>) object;
                if (list != null && list.size() > 0) {
                    for (Object obj : list) {
                        Server server = (Server) obj;
                        Class c = Class.forName(server.getService());
                        serverDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(c);
                        if (beanFactory.containsBeanDefinition(server.getName())) {
                            logger.error("webService服务{}注册失败,原因：spring中存在同名对象", server.getName());
                            continue;
                        }
                        //注册webService实现类
                        beanFactory.registerBeanDefinition(server.getName(), serverDefinitionBuilder.getRawBeanDefinition());
                        //发布
                        //Endpoint endpoint = new EndpointImpl(springBus, applicationContext.getBean(server.getName(), c));
                        //endpoint.publish("/user");
                        serverDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(EndpointImpl.class);

                        //serverDefinitionBuilder.addPropertyValue("bus",springBus);
                       // serverDefinitionBuilder.addPropertyValue("implementor",applicationContext.getBean(server.getName(), c));
                        serverDefinitionBuilder.addConstructorArgValue(springBus);
                        serverDefinitionBuilder.addConstructorArgValue(applicationContext.getBean(server.getName(),c));
                        beanFactory.registerBeanDefinition(server.getName()+"EndPoint",
                                serverDefinitionBuilder.getRawBeanDefinition() );
                        Endpoint endpoint = (Endpoint) applicationContext.getBean(server.getName()+"EndPoint");
                        endpoint.publish(server.getPublishUrl());
                        logger.info("发布{}成功",StringUtils.getNString(server.getDesc()));
                    }
                }
            }
            logger.info("初始化服务端完成....");
        } catch (Exception e) {
            logger.error("解析cxf失败", e);
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
